【opencv实践】深入理解回调函数

您所在的位置:网站首页 opencv滑动条 回调函数 【opencv实践】深入理解回调函数

【opencv实践】深入理解回调函数

2024-07-02 15:32| 来源: 网络整理| 查看: 265

前言

学弟学妹们开始学opencv了,参看的书籍是毛星云的《oepncv3编程入门》,编程环境是用的VS2017或VS2019,该项目是给他们留的第一次作业,作业内容:

读取一张图片,在该图片上截取一个ROI区域,将截取的图片在一个新的窗口内展示,并将该图片保持到工程目录下。

这个题一点也不难,因为书上给的例程已经可以完成大部分工作,只需要自己添加几行代码就可以实现上述功能,但添加这几行代码的过程可以帮助你对鼠标回调函数有一个清楚的理解。

首先我们先看一个回调函数原理:

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方法直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

如果你学过单片机,那你可以将鼠标回调函数理解为单片机的中断函数

运行机制:

⑴定义一个回调函数; ⑵函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者; ⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。

下面我们看一下opencv自带的鼠标回调函数:

void SetMouseCallback(const char* window_name, MouseCallback on_mouse, void* param = NULL); 参数window_name:为窗口的名字参数on_mouse:用来指定窗口每次鼠标时候发生的时候,被调用函数指针参数则为用户定义的传递到回调函数的参数

鼠标回调函数有很多已经定义的响应标识符,如下:

EVENT_MOUSEMOVE 鼠标移动 EVENT_LBUTTONDOWN 左键按下 EVENT_RBUTTONDOWN 右键按下 EVENT_MBUTTONDOWN 滚轮按下 EVENT_LBUTTONUP 左键抬起 EVENT_RBUTTONUP 右键抬起 EVENT_MBUTTONUP 滚轮抬起 EVENT_LBUTTONDBLCLK 左键双击 EVENT_RBUTTONDBLCLK 右键双击 EVENT_MBUTTONDBLCLK 中间双击 EVENT_FLAG_LBUTTON 左键拖拽 EVENT_FLAG_RBUTTON 右键拖拽 EVENT_FLAG_MBUTTON 中键拖拽 EVENT_FLAG_CTRLKEY 按住ctrl不放 EVENT_FLAG_SHIFTKEY 按住shift不放 EVENT_FLAG_ALTKEY 按住alt不放 下面以一学妹的程序来说一下做这个题的大体思路:

首先我们应该读取一张图片并将他显示出来,以供我们对他进行操作:

Mat srcImage; //定义图片变量 srcImage = imread("1.jpg"); //读取图片

然后我们应该定义一个鼠标回调的函数对象,也就是上面鼠标回调函数的第二个参数。我们在截取图片时的过程是这样的:

鼠标左键先按下,然后拖动鼠标成一个矩形框,然后左键松开,截出一个矩形图像。程序如下(详细注释):

//@event:鼠标事件标志(不需要自己传参) //@x:鼠标在窗口中的x坐标 //@y:鼠标在窗口中的y坐标 //@flags:自定义的宏,做标记符,Ture时开始绘制矩形,false时不绘制 //@* param:传入的图像 void on_MouseHandle(int event, int x, int y, int flags, void* param) { Mat& image = *(Mat*)param; switch (event) { //检查鼠标事件 case EVENT_MOUSEMOVE: { //如果检测到鼠标移动 if (g_bDrawingBox) { //如果绘制标识符为真,则记录下移动时矩形的宽,高 g_rectangle.width = x - g_rectangle.x; g_rectangle.height = y - g_rectangle.y; } } break; case EVENT_LBUTTONDOWN: { //检测到鼠标左键按下 g_bDrawingBox = true; //将绘制标识符设为真,准备开始绘图 g_rectangle = Rect(x, y, 0, 0); //用g_rectangle保存下起点 } break; case EVENT_LBUTTONUP: { //检测到鼠标左键抬起 g_bDrawingBox = false; //停止绘图 if (g_rectangle.width


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3